/*
 * Copyright (c) 2008-2010.
 *
 * This software is ......
 */
package com.jinmei.utils;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

/**
 * Wrapped the JSON data to response.
 * 
 * @Id JsonResponseUtil.java
 * @version
 * @author 
 * @Date Mar 27, 2009
 */
public class JsonResponseUtil {

	/** logger */
	private static Logger logger = Logger.getLogger(JsonResponseUtil.class);

	/** singleInstance */
	private static JsonResponseUtil singleInstance;

	/** contentType */
	private String contentType;

	/** charsetName */
	private String charsetName;

	/** jsonUtil */
	private JsonUtil jsonUtil;

	/**
	 * constructor.
	 */
	public JsonResponseUtil() {
		if (singleInstance == null) {
			singleInstance = this;
		}
	}

	public static JsonResponseUtil getInstance() {
		return singleInstance;
	}

	public static void writeJsonString(String jsonString) {
		singleInstance.responseJsonString(jsonString);
	}

	public static void writeJsonObject(Object data) {
		String jsonString = JsonUtil.toJsonObjectString(data);
		singleInstance.responseJsonString(jsonString);
	}

	public static void writeJsonArray(Object objectArray) {
		String jsonString = JsonUtil.toJsonArrayString(objectArray);
		singleInstance.responseJsonString(jsonString);
	}

	public static void writeAjaxResult(AjaxResult ajaxResult) {
		String jsonString = JsonUtil.toJsonString(ajaxResult);
		singleInstance.responseJsonString(jsonString);
	}

	/**
	 * @return the contentType
	 */
	public String getContentType() {
		return contentType;
	}

	/**
	 * @param contentType
	 *            the contentType to set
	 */
	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	/**
	 * @return the jsonUtil
	 */
	public JsonUtil getJsonUtil() {
		return jsonUtil;
	}

	/**
	 * @param jsonUtil
	 *            the jsonUtil to set
	 */
	public void setJsonUtil(JsonUtil jsonUtil) {
		this.jsonUtil = jsonUtil;
	}

	/**
	 * Directly Send the JSON string to client.
	 * 
	 * @param jsonString
	 */
	public void responseJsonString(String jsonString) {
		HttpServletResponse response = ServletActionContext.getResponse();
		responseJsonString(response, jsonString);
	}

	public void responseJsonObject(Object data) {
		String jsonString = jsonUtil.generateJsonObject(data);
		responseJsonString(jsonString);
	}

	public void responseJsonArray(Object objectArray) {
		String jsonString = jsonUtil.generateJsonArray(objectArray);
		responseJsonString(jsonString);
	}

	public void responseAjaxResult(AjaxResult ajaxResult) {
		String jsonString = jsonUtil.generateJsonString(ajaxResult);
		responseJsonString(jsonString);
	}

	public void setCharsetName(String charsetName) {
		this.charsetName = charsetName;
	}

	public void init() throws Exception {
		if (StringUtils.isBlank(contentType)
				|| StringUtils.isBlank(charsetName)) {
			throw new Exception(
					"Both of contentType and charsetName are requied.");
		}
	}

	/**
	 * Directly Send the JSON string to client.
	 * 
	 * @param response
	 * @param jsonString
	 */
	public void responseJsonString(HttpServletResponse response,
			String jsonString) {
		response.setContentType(contentType);
		byte[] bytes;
		try {
			bytes = jsonString.getBytes(charsetName);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		response.setContentLength(bytes.length);
		try {
			OutputStream os = response.getOutputStream();
			os.write(bytes);
			os.flush();
			if (logger.isDebugEnabled()) {
				logger.debug("Send the client" + jsonString);
			}
		} catch (IOException e) {
			logger.error("Exception happens.", e);
			throw new RuntimeException(e);
		}
	}

}
